package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.common.dto.*;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.GoodMapper;
import com.leyou.item.service.*;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class GoodServiceImpl extends ServiceImpl<GoodMapper, Spu> implements GoodService {
    @Autowired
    private SpuDetailService spuDetailService;
    @Autowired
    private GoodServiceSku goodServiceSku;
    @Autowired
    private ParamService paramService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private GoodService goodService;
    //分页查询spu
    @Override
    public PageDTO<SpuDTO> findGoodPage(Long brandId, Long categoryId, Long id, Long page, Long rows, Boolean saleable) {
        Page<Spu> spuPage = new Page<>(page, rows);

        Page<Spu> page1 = query().eq(brandId != null, "brand_id", brandId)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(id != null, "id", id)
                .eq(saleable != null, "saleable", saleable).page(spuPage);

        //解析查询结果
        long total = page1.getTotal();
        long current = page1.getCurrent();
        List<Spu> records = page1.getRecords();

        //转换成了DTO
        List<SpuDTO> spuDTOS = SpuDTO.convertEntityList(records);
        for (SpuDTO spuDTO : spuDTOS) {
            //查询CategoryName, brandName
            handBrandNameAndCategoryName(spuDTO);
        }
        return new PageDTO<>(total,current,spuDTOS);
    }

    private void handBrandNameAndCategoryName(SpuDTO spuDTO) {
        Brand brand = brandService.getById(spuDTO.getBrandId());
        if (brand!=null){
            spuDTO.setBrandName(brand.getName());
        }
        Category category = categoryService.getById(spuDTO.getCid3());
        if (category!=null){
            spuDTO.setCategoryName(category.getName());
        }
    }

    //根据id查询spu及sku、spuDetail等
    @Override
    public SpuDTO QuerySpuAndSkuAndSpuDetails(Long id) {
        //根据spuId查询spu转为SpuDTO
        SpuDTO spuDTO = new SpuDTO(getById(id));

        //根据brandId以及categoryIds查询对应的分类及品牌名称
        spuDTO.setCategoryName(getCategoryName(spuDTO.getCategoryIds()));
        spuDTO.setBrandName(getBrandName(spuDTO.getBrandId()));

        spuDTO.setSpuDetail(new SpuDetailDTO(this.spuDetailService.getById(spuDTO.getId())));

        //给spu赋值skus，select * from tb_sku where spu_id = #{spuId}
        spuDTO.setSkus(
                SkuDTO
                        .convertEntityList(
                                this.goodServiceSku
                                        .query()
                                        .eq("spu_id", spuDTO.getId())
                                        .list()));


        return spuDTO;
    }
    private String getCategoryName(List<Long> cids) {
        //根据分类id的集合查询对应的分类的集合
        return this.categoryService
                .findCategoryById(cids)
                .stream()
                .map(CategoryDTO::getName)
                .collect(Collectors.joining("/"));
    }

    private String getBrandName(Long brandId) {
        return this.brandService.getById(brandId).getName();
    }
    //新增商品
    @Override
    public void addGoods(SpuDTO spuDTO) {
        //新增商品涉及的是三张表 tb_sku,tb_spu,tb_spu_detail
        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(false);
        //如果spu表中插入数据成功后向tb_spu_detail表中插入数据
        if(this.save(spu)) {
            SpuDetail spuDetail = spuDTO.toEntity(SpuDetail.class);
            spuDetail.setSpuId(spu.getId());
            spuDetailService.save(spuDetail);

            //向tb_sku表中插入数据
            List<Sku> skuList = spuDTO.getSkus().stream().map(skuDTO -> {
                Sku sku = skuDTO.toEntity(Sku.class);
                sku.setId(spu.getId());
                return sku;
            }).collect(Collectors.toList());

            //批量新增
            this.goodServiceSku.saveBatch(skuList);
        }
    }

    @Override
    public List<SpecParamDTO> QuerySpectParam(Long id, Boolean searching) {

        List<SpecParamDTO> specParamDTOS = this.paramService.QuerySpectParam(null, getById(id).getCid3(),searching);

        //获取规格属性的键值对，key为规格参数的id，value为对应的规格值，nativeRead，json粉碎机，什么类型都可以处理
        Map<Long,Object> specMap = JsonUtils.nativeRead(
                this.spuDetailService.getById(id).getSpecification(),
                new TypeReference<Map<Long, Object>>() {
                });

        //循环给规格参数添加属性，value
        specParamDTOS.forEach(specParamDTO -> {
            specParamDTO.setValue(specMap.get(specParamDTO.getId()));
        });

        return specParamDTOS;

    }
    @Autowired
    private AmqpTemplate amqpTemplate;

    //修改商品上下架
    @Override
    public void modifyGoods(Long id, Boolean saleable) {
        // 1.更新SPU
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        updateById(spu);
        Sku sku = new Sku();
        sku.setSaleable(saleable);
        //update tb_sku set saleable = true where spu_id = 2
        this.goodServiceSku.update(sku, new QueryWrapper<Sku>().eq("spu_id", id));
        String key = saleable?"item.up":"item.down";
        //生产者发送消息
        this.amqpTemplate.convertAndSend("shangPin",key,id);
    }
     //修改商品
    @Override
    public void modifyGood(SpuDTO spuDTO) {
        //id为空
        if(null==spuDTO.getId()&&null==spuDTO.getSpuDetail().getSpuId()&&(null==spuDTO.getSkus()&&spuDTO.getSkus().size()!=0)){
            return;
        }
        //spu的id不为空
        if (spuDTO.getId()!=null){
           saveOrUpdate(spuDTO.toEntity(Spu.class));
        }
        //spu的spudetail的id需要修改
        if(spuDTO.getSpuDetail().getSpuId()!=null){
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
            this.spuDetailService.saveOrUpdate(spuDetail);
        }
        if(spuDTO.getSkus()!=null&&spuDTO.getSkus().size()!=0) {

            Map<Boolean, List<Sku>> skuMap = spuDTO.getSkus().stream().map(skuDTO -> skuDTO.toEntity(Sku.class))
                    .collect(Collectors.groupingBy(sku -> {
                        return sku.getSaleable() == null;
                    }));

            this.goodServiceSku.saveOrUpdateBatch(skuMap.get(true));

            //为false的一组表示要删除
            this.goodServiceSku.removeByIds(skuMap.get(false).stream().map(Sku::getId).collect(Collectors.toList()));
        }
    }
}
